export default class QuotedPrintable {
  static Options = {
    wordMode: {
      type: 'switch',
      label: 'Word Mode'
    }
  }

  options = {
    wordMode: false
  }

  static Encoder = class Encoder extends QuotedPrintable {
    static Name = "Quoted-Printable <%= UIText.encode %>";

    compute(bytes) {
      let chr, out = '', len = bytes.length;

      for( let i = 0; i < len; i++ ) {
        chr = bytes[i]
        if( this.options.wordMode ) {
          // if matches /[\x3D]|[^\x09\x0D\x0A\x20-\x7E]/gm
          out = chr !== 0x3D && ( chr >= 0x20 && chr <= 0x007E ) || ( chr === 0x09 || chr === 0x0D || chr === 0x0A )
            ? out + String.fromCharCode( chr )
            : out + '=' + (chr < 0x10 ? '0' : '') + chr.toString(16).toUpperCase()
        } else {
          // if matches /[\x3D\x5F\x3F]|[^\x21-\x7E]/gm
          out = (chr !== 0x3D && chr !== 0x5F && chr !== 0x3F) && (chr >= 0x21 && chr <= 0x007E)
            ? out + String.fromCharCode( chr )
            : out + '=' + (chr < 0x10 ? '0' : '') + chr.toString(16).toUpperCase()
        }
      }

      return out
    }
  }

  static Decoder = class Decoder extends QuotedPrintable {
    static Name = "Quoted-Printable <%= UIText.decode %>";

    compute(input) {
      let bytes = []

      if( !this.options.wordMode ) {
        input = input.replace( /[=]\r?\n/gm, '' )
        input = input.replace( /[=]$/, '' )
      } else {
        input = input.replace( /_/g, ' ' )
      }

      input.replace( /[=]([A-F0-9]{2})|(.|[\u0000-\uFFFF])/g, function( match, hex, chr ) {
        bytes.push( hex ? parseInt( hex, 16 ) : chr.charCodeAt( 0 ) )
      })

      return new Buffer( bytes )
    }
  }
}
